#pragma once

#include <atlgdi.h>
#include <imaging.h>
#include <ZipFile.h>
#include <vector>
#include "SettingsDef.h"
#include "Settings.h"

#define THEME_FILE_EXT        TEXT(".cthm")
#define THEME_INI_FILE        TEXT("theme.txt")

class CImage
{
public:
  IImage* image;
  int     width;
  int     height;

  CImage(bool bHandle = false) : width(0), height(0), image(NULL), handle(bHandle)
  {}
  CImage(const CImage& b) : width(b.width), height(b.height), image(b.image), handle(false)
  {}
  ~CImage()
  { if (handle && image) image->Release(); }

  CImage& operator= (const CImage& b)
  {
    if (this != &b)
    {
      if (handle && image) image->Release(); 
      width = b.width; height = b.height; image = b.image; handle = false;
    }
    return *this;
  }

  bool IsValid() const
  { return image != NULL; }
  void Draw(HDC hdc, int x, int y) const
  { Draw(hdc, x, y, x + width, x + height); }
  void Draw(HDC hdc, int x, int y, int w, int h) const
  { if (image) { RECT rc = {x, y, x + w, y + h}; image->Draw(hdc, &rc, NULL); } }
  void Draw(HDC hdc, const RECT& rc) const
  { if (image) { image->Draw(hdc, &rc, NULL); } }
  void Draw(HDC hdc, const RECT& rcDst, const RECT& rcSrc) const
  { if (image) { image->Draw(hdc, &rcDst, &rcSrc); } }

private:
  bool   handle;
};

class CThemeFont
{
public:
  CFont font;
  bool  bold;
  bool  italic;
  int   size;

  CThemeFont() : bold(false), italic(false), size(0)
  {}
};

class CScreenDC : public CDC
{
public:
  CScreenDC();
  ~CScreenDC();
protected:
	CBitmap m_bmp;
	HBITMAP m_hBmpOld;
};

class CTheme
{
public:   // INITIALIZATION

  static bool Initialize();
  static void Terminate();

public:   // DATA
  static COLORREF clrWindowBg;
  static CBrush   brWindowBg;
  static COLORREF clrWindowEdge;

  static int    iLongTapIndWidth;
  static COLORREF clrLongTap;
  static COLORREF clrLongTapFull;
  static CBrush brLongTap;
  static CBrush brLongTapFull;

  static int    iListScrollbarWidth;
  static COLORREF clrListScrollbarBg;
  static COLORREF clrListScrollbar;
  static CBrush   brListScrollbarBg;
  static CBrush   brListScrollbar;

  static CBrush   brListBg;
  static COLORREF clrListBg1;
  static COLORREF clrListBg2;
  static COLORREF clrListItemSelBg1;
  static COLORREF clrListItemSelBg2;
  static COLORREF clrListItemSeparator;
  static CBrush   brListItemSeparator;
  static COLORREF clrListItemText;
  static COLORREF clrListItemSelText;
  static CThemeFont fntListItem;

  static CThemeFont fntLayoutLbl;
  static CThemeFont fntLayoutLblSmall;
  static COLORREF clrLayoutLbl;
  static COLORREF clrLayoutLblSel;
  static CThemeFont fntLayoutText;
  static CThemeFont fntLayoutInt;

  static COLORREF clrEditBox;
  static CThemeFont fntEditBox;
  static COLORREF clrEditBoxBg;
  static CBrush   brEditBox;

  static COLORREF clrPopupHeader;
  static CThemeFont fntPopupHeader;
  static COLORREF clrPopupHeaderBg;
  static CBrush   brPopupHeader;

  static int iListItemIndent;
  static int iListItemSize;
  static int iSelectorListItemSize;

public:   // PUBLIC INTERFACE

  static CImage GetImage(EThemeImages image);
  static CImage GetImage(const TCHAR* name);
  static bool CreateBitmap(IImage* pImage, CBitmap& bitmap, int& width, int& height, COLORREF bgColor = 0);

public:   // GRAPHICS FUNCTIONS
  static void DrawGradientGDI(HDC, const RECT&, COLORREF, COLORREF);
  static void DrawGradientGDI(HDC, const RECT& iClip, const RECT& iRect, COLORREF, COLORREF);

  static void BltAlpha(HDC hdcDest, int dx, int dy, int dw, int dh, HDC hdcSrc, int sx, int sy, BYTE alpha)
  { CTheme::BltAlpha(hdcDest, dx, dy, dw, dh, hdcSrc, sx, sy, dw, dh, alpha); }
  static void BltAlpha(HDC hdcDest, int dx, int dy, int dw, int dh, HDC hdcSrc, BYTE alpha)
  { CTheme::BltAlpha(hdcDest, dx, dy, dw, dh, hdcSrc, dx, dy, dw, dh, alpha); }
  static void BltAlpha(HDC, int, int, int, int, HDC, int, int, int, int, BYTE alpha);

  static COLORREF GetMedianColor(COLORREF clr1, COLORREF clr2);

protected:

  static bool CreateColor(COLORREF& clr, CIniHandler& ini, EThemeItems id);
  static bool CreateGrad(COLORREF& clr1, COLORREF& clr2, CIniHandler& ini, EThemeItems id);
  static bool CreateFont(CThemeFont& font, CIniHandler& ini, EThemeItems id);
  static bool CreatePen(CPen& pen, CIniHandler& ini, EThemeItems id);

  // SETTINGS
  static bool LoadSettings(CZipFile& zip);

  // IMAGES
  static bool LoadImages(CZipFile& zip);
  static bool ReadImage(CZipFile& zip, DWORD dwSize, const TCHAR* szName, IImagingFactory* pFactory);
  static bool ReadImageFromBuf(const void* pBuf, DWORD nSize, IImage** pImage, IImagingFactory* pFactory);
  static void ReleaseImages();

protected:
  struct SImageData
  {
    CString name;
    EThemeImages id;
    CImage  image;

    SImageData() : id(timUnknown), image(true)
    {}
  };
  typedef std::vector<SImageData*> CImageVector;

  static CImageVector images;
};
